package cn.sample.moreitems.entity;

import cn.sample.moreitems.block.TechnologyBlock;
import cn.sample.moreitems.init.ModEntities;
import cn.sample.moreitems.init.ModItems;
import cn.sample.moreitems.item.ThrownRockItem;
import cn.sample.moreitems.menu.TechnologyMenu;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.SmeltingRecipe;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.items.ItemStackHandler;

import javax.annotation.Nullable;

public class TechnologyEntity extends BlockEntity implements MenuProvider {

    /* 三槽：0燃料 1原料 2产物 */
    private final ItemStackHandler inventory = new ItemStackHandler (3);
    /* 燃烧状态 */
    private int burnTime, burnTimeTotal, cookTime, cookTimeTotal;

    public TechnologyMenu getMenu() {
        return menu;
    }

    public void setMenu(TechnologyMenu menu) {
        this.menu = menu;
    }

    private TechnologyMenu menu;

    public TechnologyEntity(BlockPos p, BlockState s) {
        super(ModEntities.FUEL_BURNER_BE.get(), p, s);
    }

    /* 每 tick 逻辑 */
    public static void serverTick(Level lvl, BlockPos p, BlockState s, TechnologyEntity be) {
        if (be.isBurning()) be.burnTime--;

        ItemStack fuel = be.inventory.getStackInSlot(0);
        ItemStack input = be.inventory.getStackInSlot(1);

        SmeltingRecipe recipe = be.getRecipeFor(input);
        /* 1. 如果需要且能烧 */
        if (!be.isBurning() && be.canBurn(fuel, input, recipe)) {
            be.burnTimeTotal = be.getBurnDuration(fuel);
            be.burnTime = be.burnTimeTotal;
            if (!fuel.isEmpty()) fuel.shrink(1);
            be.cookTimeTotal = recipe.getCookingTime();
        }
        /* 2. 正在烧 */
        if (be.isBurning() && be.canBurn(fuel, input, recipe)) {
            be.cookTime++;
            if (recipe != null && be.cookTime == recipe.getCookingTime()) {
                be.cookTime = 0;
                be.smeltRecipe(recipe);
            }
        } else {
            be.cookTime = 0;
        }
        /* 3. 状态同步 */
        if (s.getValue(TechnologyBlock.LIT) != be.isBurning()) {
            lvl.setBlock(p, s.setValue(TechnologyBlock.LIT, be.isBurning()), 3);
        }
        TechnologyMenu menu1 = be.getMenu();
        if (menu1 != null) {
            menu1.setPrice(be.getBurnProgress());
            menu1.setPrice2(be.getCookProgress());
        }

    }

    private boolean isBurning() { return burnTime > 0; }
    private boolean canBurn(ItemStack fuel, ItemStack input, @Nullable SmeltingRecipe r) {
        return !fuel.isEmpty() && r != null && canOutputFit(r);
    }
    private boolean canOutputFit(SmeltingRecipe r) {
        ItemStack out = new ItemStack(ModItems.THROWN_ROCK.get(), 1);
        return inventory.getStackInSlot(2).isEmpty() ||
                ItemStack.isSameItemSameTags(inventory.getStackInSlot(2), out) &&
                        inventory.getStackInSlot(2).getCount() + out.getCount() <= out.getMaxStackSize();
    }


    private void smeltRecipe(SmeltingRecipe r) {
        ItemStack out = new ItemStack(ModItems.THROWN_ROCK.get(), 1);
        ItemStack slot = inventory.getStackInSlot(2);
        if (slot.isEmpty()) inventory.setStackInSlot(2, out.copy());
        else slot.grow(out.getCount());
        inventory.getStackInSlot(1).shrink(1);
        setChanged();
    }
    @Nullable
    private SmeltingRecipe getRecipeFor(ItemStack stack) {
        if (level == null) return null;
        return level.getRecipeManager().getRecipeFor(RecipeType.SMELTING, new SimpleContainer(stack), level).orElse(null);
    }
    private int getBurnDuration(ItemStack fuel) {
        return AbstractFurnaceBlockEntity.getFuel().get(fuel.getItem());
//        return ForgeEventFactory.getItemBurnTime(fuel, -1, RecipeType.SMELTING);
    }

    /* 数据保存与同步略 */
    @Override
    public AbstractContainerMenu createMenu(int id, Inventory inv, Player p) {
        menu = new TechnologyMenu(id, inv, ContainerLevelAccess.create(level, worldPosition), this);
        return menu;
    }
    public ItemStackHandler  getInventory() { return inventory; }
    public int getBurnProgress() { return burnTimeTotal == 0 ? 0 : (burnTime * 13) / burnTimeTotal; }
    public int getCookProgress() { return cookTimeTotal == 0 ? 0 : (cookTime * 24) / cookTimeTotal; }


    @Override
    public Component getDisplayName() {
        return Component.translatable("kejiwu");
    }

    @Override
    protected void saveAdditional(CompoundTag tag) {
        super.saveAdditional(tag);
        tag.put("inv", inventory.serializeNBT());   // 关键
    }

    @Override
    public void load(CompoundTag tag) {
        super.load(tag);
        inventory.deserializeNBT(tag.getCompound("inv")); // 关键
    }



}
